# 最低版本限制
cmake_minimum_required(VERSION 3.20.0)
# 指定项目名称
project(XXX CXX)

#设置c++编译器
set(CXX "g++")
set(CMAKE_TOOLCHAIN_FILE /usr/bin/g++)
# 高手再使用clang++
#set(CXX "clang++")

#[[
- 启用最高级别的优化 (-O3)。
- 开启大多数有用的警告信息 (-Wall)。
- 启用额外的警告信息 (-W)。
- 要求编译器严格遵守 C++ 标准 (-pedantic)。
- 生成二进制文件要包含调试信息(-g)
]]
# Debug版本
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -Wall -W -pedantic -g -DDEBUG")
# Release版本
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -Wall -W -pedantic -DNODEBUG")

# 设置C++标准
set(CMAKE_CXX_STANDARD 20)
# 生成compile_commands.json 文件 供智能提示使用
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
#启用单元测试
#enable_testing()
#加入单元测试文件夹
#add_subdirectory(tests)

#[[ 用于指定链接阶段使用 LLVM 的链接器 LLD（LLVM Linker）而不是系统默认的链接器, 是 Clang 编译器的一个命令行选项
确保自己的系统安装了lld 链接器。请使用which lld 查看，如果没有请先安装
]]
# Use lld to avoid https://github.com/fmtlib/fmt/issues/4156
# 注释时使用默认链接器
# set(CMAKE_EXE_LINKER_FLAGS "-fuse-ld=lld")


#[[ 
这段 CMake 代码是用来配置项目以支持 AddressSanitizer (ASan)，这是一个用于检测内存错误（如使用未初始化的内存、缓冲区溢出等）的强大工具]]
# address sanitizer
option(ENABLE_ASAN "Enable AddressSanitizer" OFF)
if(ENABLE_ASAN)
    # tips: install llvm-symbolizer to show more reable message
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address -fno-omit-frame-pointer -g")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -g")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer -g")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
endif()

# 设置默认构建类型
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE)
endif()

# 设置宏定义--可选
# 比如 自定义多个宏  DEBUG CARDNUM 宏
#add_definitions(-DDEBUG -DCARDNUM)

set(TARGET_NAME app)

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/bin)
# 第三方lib库要么加到环境变量/etc/profile 中  LD_LIBRARY_PATH (推荐); 
# 要么在makefile里明确指定
#set(REF_LIBRARY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/BigNumber/lib")

# 支持递归 可以去掉src时就包含main.cpp了
file(GLOB_RECURSE SRC_LIST 
"${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/BigNumber/src/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/fmt/src/*.cc"
#"${CMAKE_CURRENT_SOURCE_DIR}/chapter10-10/*.cpp"
#"${CMAKE_CURRENT_SOURCE_DIR}/chapter10-11/*.cpp"
#"${CMAKE_CURRENT_SOURCE_DIR}/chapter10-12/*.cpp"
#"${CMAKE_CURRENT_SOURCE_DIR}/chapter10-13/*.cpp"
#"${CMAKE_CURRENT_SOURCE_DIR}/chapter10-14/*.cpp"
)

add_executable(${TARGET_NAME}  ${SRC_LIST} 
#lesson13.5.4.cpp
#lesson14.3.3.cpp
#lesson14.3.6.cpp
lesson14.3.7.cpp

)

target_include_directories(${TARGET_NAME} PUBLIC 
${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/BigNumber/include
${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/fmt/include
${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/cereal/include
${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/miniz-cpp
${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/rapidcsv/src
#${CMAKE_CURRENT_SOURCE_DIR}/chapter10-10/
#${CMAKE_CURRENT_SOURCE_DIR}/chapter10-11/
#${CMAKE_CURRENT_SOURCE_DIR}/chapter10-12/
#${CMAKE_CURRENT_SOURCE_DIR}/chapter10-13/
#${CMAKE_CURRENT_SOURCE_DIR}/chapter10-14/
)
# item 自己补全
target_link_libraries(${TARGET_NAME} PUBLIC BigNumber fmt)
#REF_LIBRARY_PATH 如果指定 这行就加上  
target_link_directories(${TARGET_NAME} PUBLIC 
"${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/BigNumber/lib"
"${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/fmt/lib"
)
# target_compile_options(${TARGET_NAME} PRIVATE
#     -Wall 
#     -Wextra 
#     -Wno-interference-size 
#     -Werror=return-type
#     -Werror=unused-result 
#     -Werror=uninitialized 
#     -Werror=maybe-uninitialized
#     -Wno-unused-parameter 
#     -Wunused-but-set-variable 
#     -Wunused-but-set-parameter 
#     -Wunused-function
#     -Wunused-const-variable 
#     -Werror=use-after-free=3 
#     -Werror=invalid-memory-model 
#     -Wunused-value
#     -Wexceptions 
#     -Werror=missing-declarations 
#     -Werror=missing-field-initializers
#     -Wparentheses 
#     -Wconversion 
#     -Werror=float-conversion 
#     -Wsign-conversion 
#     -Wsign-compare 
#     -Wno-terminate
#     -Werror=delete-non-virtual-dtor 
#     -Werror=suggest-override 
#     -Wsign-promo 
#     -Wold-style-cast
#     -Wrange-loop-construct 
#     -Werror=reorder 
#     -Werror=class-memaccess 
#     -Werror=narrowing
#     -Wdeprecated-enum-enum-conversion 
#     -Werror=deprecated-copy-dtor 
#     -Werror=deprecated-copy
#     -Wzero-as-null-pointer-constant 
#     -Wplacement-new=2 
#     -Wsuggest-final-types 
#     -Wsuggest-final-methods
#     -Werror=conversion-null 
#     -Werror=mismatched-new-delete 
#     -Werror=address 
#     -Wlogical-op 
#     -Wlogical-not-parentheses
#     -Wattributes 
#     -Wmissing-declarations 
#     -Werror=multichar 
#     -Werror=overflow 
#     -Werror=restrict 
#     -Werror=vla
#     -Wstrict-aliasing=1 
#     -Werror=string-compare 
#     -Werror=stringop-overflow=2 
#     -Werror=shift-overflow
#     -Wsuggest-attribute=const 
#     -Wsuggest-attribute=pure 
#     -Wsuggest-attribute=noreturn 
#     -Werror=alloca
#     -Werror=array-bounds 
#     -Werror=bool-compare 
#     -Werror=bool-operation 
#     -Werror=zero-length-bounds
#     -Werror=div-by-zero 
#     -Wno-shadow 
#     -Werror=format 
#     -Werror=pointer-arith 
#     -Werror=write-strings
#     -Werror=dangling-pointer=2 
#     -Werror=return-local-addr 
#     -Wempty-body 
#     -Wimplicit-fallthrough
#     -Wswitch 
#     -Wno-unknown-warning-option)